#include "MultiPassRenderer.h"

MultiPassRenderer::MultiPassRenderer()
{
	initializeRenderBuffer(_buffers[0]);
	initializeRenderBuffer(_buffers[1]);
	_startingSprite = new sf::Sprite();
}

MultiPassRenderer::~MultiPassRenderer()
{
	delete _buffers[0].sprite;
	delete _buffers[0].renderTexture;
	delete _buffers[1].sprite;
	delete _buffers[1].renderTexture;
}

void MultiPassRenderer::create(unsigned int width, unsigned int height)
{
	createRenderBuffer(_buffers[0], width, height);
	createRenderBuffer(_buffers[1], width, height);

	_buffers[0].sprite->setTexture(_buffers[1].renderTexture->getTexture(), true);
	_buffers[1].sprite->setTexture(_buffers[0].renderTexture->getTexture(), true);
}

MultiPassRenderer& MultiPassRenderer::startWith(const sf::Texture& texture, bool clearShaderStack)
{
	_startingTexture = &texture;
	_startingSprite->setTexture(texture, true);
	if (clearShaderStack) clearShaders();
	return *this;
}

MultiPassRenderer& MultiPassRenderer::continueWith(sf::Shader& shader, int passAmount, bool hasTexture)
{
	_shaders[_nbShaders].shader = &shader;
	_shaders[_nbShaders].passAmount = passAmount;
	_shaders[_nbShaders].hasTexture = hasTexture;
	_nbShaders++;

	return *this;
}

void MultiPassRenderer::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
	if (_nbShaders > 0)
	{
		/*_shaders[0].shader->setParameter("texture", *_startingTexture);
		_buffers[0].renderTexture->clear(sf::Color::Transparent);
		_buffers[0].renderTexture->draw(*_startingSprite, _shaders[0].shader);
		_buffers[0].renderTexture->display();*/
		_shaders[0].shader->setParameter("texture", *_startingSprite->getTexture());
		target.clear(sf::Color::Transparent);
		target.draw(*_startingSprite, _shaders[0].shader);
		((sf::RenderTexture&)target).display();
		for (int i = 1; i < _nbShaders; i++)
		{
			const RenderBuffer& buffer = _buffers[i%2];
			sf::RenderTarget* renderTarget =
				i < _nbShaders - 1
					? buffer.renderTexture
					: &target;
			_shaders[i].shader->setParameter("texture", _buffers[(i + 1) % 2].renderTexture->getTexture());
			renderTarget->clear(sf::Color::Transparent);
			renderTarget->draw(*buffer.sprite, _shaders[i].shader);
			((sf::RenderTexture*)renderTarget)->display();
		}
	}
}



void MultiPassRenderer::createRenderBuffer(RenderBuffer& renderBuffer, unsigned int width, unsigned int height)
{
	renderBuffer.renderTexture->create(width, height);
}


void MultiPassRenderer::initializeRenderBuffer(RenderBuffer& renderBuffer)
{
	renderBuffer.sprite = new sf::Sprite();
	renderBuffer.renderTexture = new sf::RenderTexture();
	renderBuffer.renderTexture->clear();
}

void MultiPassRenderer::clearShaders()
{
	_nbShaders = 0;
}